home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / oper_sys / presto / prest_04.lha / src / sequent / SLOCK.c < prev    next >
Encoding:
C/C++ Source or Header  |  1989-06-06  |  2.8 KB  |  129 lines

  1. /*  PRESTO: SLOCK.c
  2.  *
  3.  *  The purpose of this module is to provide out-of-line procedure
  4.  *  definitions for S_LOCK, etc., since C++ doesn't understand
  5.  *  asm-functions.  The preferred solution to this problem, however,
  6.  *  is to use "CC +h/usr/include/Presto/asmdefs.h file.c";
  7.  *  this causes the asm-function definitions to be slipped into
  8.  *  file..c before cc is called.
  9.  *
  10.  *  This code is lifted straight out of <parallel/parallel.h>.
  11.  *  Copyright Sequent Computer, etc.
  12.  */
  13.  
  14. #ifdef i386
  15.  
  16. /*
  17.  * A "lock" is a byte of memory, initialized to zero (unlocked).
  18.  */
  19. typedef unsigned char   slock_t;
  20.  
  21. #define L_UNLOCKED      0
  22. #define L_LOCKED        1
  23.  
  24. /*
  25.  * Was a conditional lock request granted (L_SUCCESS) or denied (L_FAILED)
  26.  */
  27. #define L_FAILED        0
  28. #define L_SUCCESS       1
  29.  
  30. /*
  31.  * S_LOCK() S_UNLOCK(), S_CLOCK(), and S_INIT_LOCK functions.
  32.  * These are implemented as "asm functions", and will produce very good code.
  33.  *
  34.  * Need to use the -i flag with the optimizer when these inline functions are
  35.  * used. (cc -O -i).   This is to prevent the optimizer from removing
  36.  * "redundant" moves (which aren't really redundant in this case)
  37.  * in the spin loops.
  38.  */
  39.  
  40. asm void LOCK(laddr)
  41. {
  42. %reg laddr; lab loop, spin, done;
  43. /PEEPOFF
  44. loop:    movb    $L_LOCKED, %al
  45.     xchgb    %al, (laddr)        /* an atomic "test and set" */
  46.     cmpb    $L_UNLOCKED, %al
  47.     je    done            /* if equal, we got the lock */
  48. spin:    cmpb    $L_UNLOCKED, (laddr)    /* spin in cache until unlocked */
  49.     je    loop            /* then, try get lock again */
  50.     jmp    spin
  51. done:
  52. /PEEPON
  53. %mem laddr; lab loop, spin, done;
  54. /PEEPOFF
  55. loop:    movb    $L_LOCKED, %al
  56.     movl    laddr, %ecx
  57.     xchgb    %al, (%ecx)        /* an atomic "test and set" */
  58.     cmpb    $L_UNLOCKED, %al
  59.     je    done            /* if equal, we got the lock */
  60. spin:    cmpb    $L_UNLOCKED, (%ecx)    /* spin in cache until unlocked */
  61.     je    loop            /* then, try get lock again */
  62.     jmp    spin
  63. done:
  64. /PEEPON
  65. }
  66.  
  67. asm void UNLOCK(laddr)
  68. {
  69. %reg laddr;
  70.     movb    $L_UNLOCKED, %al
  71.     xchgb    %al, (laddr)        /* clear lock, "atomically" */
  72. %mem laddr;
  73.     movb    $L_UNLOCKED, %al
  74.     movl    laddr, %ecx
  75.     xchgb    %al, (%ecx)        /* clear lock, "atomically" */
  76. }
  77.  
  78. asm CLOCK(laddr)
  79. {
  80. %reg laddr; lab done;
  81.     movb    $L_LOCKED, %dl
  82.     movl    $L_SUCCESS, %eax
  83.     xchgb    %dl, (laddr)        /* test and set lock */
  84.     cmpb    $L_UNLOCKED, %dl    /* if we got it, return success */
  85.     je    done
  86.     movl    $L_FAILED, %eax        /* else return failure */
  87. done:
  88. %mem laddr; lab done;
  89.     movb    $L_LOCKED, %dl
  90.     movl    laddr, %ecx
  91.     movl    $L_SUCCESS, %eax
  92.     xchgb    %dl, (%ecx)        /* test and set lock */
  93.     cmpb    $L_UNLOCKED, %dl    /* if we got it, return success */
  94.     je    done
  95.     movl    $L_FAILED, %eax        /* else return failure */
  96. done:
  97. }
  98.  
  99. #define INIT_LOCK(lp)    UNLOCK(lp)
  100.  
  101.  
  102. S_INIT_LOCK(lock)
  103.     slock_t    *lock;
  104. {
  105.     UNLOCK(lock);
  106. }
  107.  
  108.  
  109. S_LOCK(lock)
  110.     register slock_t *lock;
  111. {
  112.     LOCK(lock);
  113. }
  114.  
  115.  
  116. S_UNLOCK(lock)
  117.     slock_t    *lock;
  118. {
  119.     UNLOCK(lock);
  120. }
  121.  
  122. S_CLOCK(lock)
  123.     slock_t *lock;
  124. {
  125.     CLOCK(lock);
  126. }
  127.  
  128. #endif i386
  129.